//
// Created by DengLibin on 2018/12/13 0013.
//

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <algorithm>
#include <functional>
using namespace std;
template <typename T>
class IsDiv
{
public:
    IsDiv(const T &divsor)
    {
        this->divsor = divsor;
    }
    //谓词函数是一个判断式，一个返回bool值的函数或者仿函数
    //接受一个参数的函数，叫做一元函数，如果一元函数返回布尔值，则该函数成为一元谓词；
    //接受两个参数的函数为二元函数，如果返回一个布尔值，则该函数称为二元谓词。
    bool operator()(T &t)
    {
        return (t%divsor == 0);
    }
private:
    T divsor;
};
//一元谓词的使用
void wei_ci()
{
    vector<int> v;
    for (int i = 0; i < 10; i++)
    {
        v.push_back(i);
    }
    int a = 4;
    IsDiv<int> myDiv(a);
    //查找能被a整除的元素
    vector<int>::iterator  it = find_if(v.begin(), v.end(), myDiv);
    while (it != v.end())
    {
        cout << "被4整除的元素是:" << *it << endl;
        it++;
        it = find_if(it, v.end(), myDiv);

    }
}
//二元函数对象
template <typename T>
class SumAdd
{
public:
    T operator()(T &t1, T &t2)
    {
        return t1 + t2;
    }
};
void er_yuan_wei_ci()
{
    vector<int> v1, v2, v3;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);

    v2.push_back(4);
    v2.push_back(5);
    v2.push_back(6);

    v3.resize(10);//调整容器的长度大小，使其能容纳n个元素。如果n小于容器的当前的size，则删除多出来的元素。否则，添加采用值初始化的元素。
    /*
    OutputIterator transform ( InputIterator1 first1,     // 源容器1的起始地址
    InputIterator1 last1,       // 源容器1的终止地址
    InputIterator2 first2,      // 源容器2的起始地址，元素个数与1相同
    OutputIterator result,      // 目标容器的起始地址，元素个数与1相同
    BinaryOperator binary_op ); // 函数指针
    */
    //两个容器中对应位置的元素求和插入到第三个容器中，返回第三个容器插入最后一个元素的后一个元素迭代器
    vector<int>::iterator it = transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), SumAdd<int>());

    for (it--; it != v3.begin() - 1; it--)
    {
        cout << *it << "\t" << endl; //9 7 5
    }
}
/*
预定义的函数对象:
加法：plus<Types>
减法：minus<Types>
乘法：multiplies<Types>
除法divides<Tpye>
求余：modulus<Tpye>
取反：negate<Type>

等于equal_to<Tpye>
不等于not_equal_to<Type>
大于 greater<Type>
大于等于greater_equal<Type>
小于 less<Type>
小于等于less_equal<Type>
*/
//用于比较的谓词
template <typename T>
class MyCompare
{
public:
    bool operator()(const T &t1, const T &t2)
    {
        return  t1 < t2;
    }
};
//用于遍历的函数
template <typename T>
void print_ele(T &t)
{
    cout << t << "\t";
}
void compare_weici()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(9);
    v1.push_back(3);
    v1.push_back(8);
    v1.push_back(5);
    v1.push_back(7);
    //排序
    sort(v1.begin(), v1.end(), MyCompare<int>());
    //遍历
    for_each(v1.begin(), v1.end(), print_ele<int>);

}

//自定义set的排序
//仿函数
struct CompareNoCase
{
    //不区分大小写
    bool  operator()(const string &str1, const string &str2)const  //加const修饰，不能修改成员变量
    {

        string str1_;
        string str2_;
        str1_.resize(str1.size());
        str2_.resize(str2.size());
        //转小写
        transform(str1.begin(), str1.end(), str1_.begin(), ::tolower);
        transform(str2.begin(), str2.end(), str2_.begin(), ::tolower);
        return str1_ < str2_;//从小到大排列
    }
};

void my_set()
{
    set<string, CompareNoCase> s;
    s.insert("AAA");
    s.insert("bbb");
    s.insert("ddd");
    s.insert("GGG");
    s.insert("ccc");
    s.insert("EEE");

    for (set<string, CompareNoCase>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << "\t";
    }
    cout << endl;
    //查找，不区分大小写
    set<string, CompareNoCase>::iterator it = s.find("aaa");
    cout << *it << endl;
}

int main31()
{
    //wei_ci();
     //er_yuan_wei_ci();
    //compare_weici();
   // my_set();
    return 0;
}